#pragma once
#include <functional>
#include <mutex>
#include <vector>

#include "BondContainer.h"
#include "SSSortInfo.h"
#include "StringPtrMap.h"
#include "bondlib.h"

#ifdef CCORE_LINUX
#include <tr1/functional>
#endif

#ifndef IN
#define IN
#endif

#ifndef OUT
#define OUT
#endif
// ***************************************************************
//  SSVContainer   version:  10.0
//  -------------------------------------------------------------
//  author:	Tony.luo
//    date: 2015-07-14
//   brief:
//		    1、新增加易用性更好接口
//          2、增加类的常用说明
//    由于SSVContainer类干得活太多了，不是单一缓存债券容器类，没有很好遵守“开-闭”，接口隔离等原则，使用是要特别注意
//	  主要说明：
//      1)、成员m_array_result为基础数据，一般是从检索函数中得到内容
//      2)、成员m_brokevec是从基础数据m_array_result映射一份与broker相关的数据，
//	        目的是为了支持broker之间的排序，界面中大多是使用m_brokevec.m_vct数据
//          排序算法也主要是针对m_brokevec.m_vct
//		3)、ss_sort()排序函数只有在参数bSave设置true时才会修改自身m_brokevec.m_vct数据
//          排序算法调用时，需详细了解参数说明
//      4)、过滤Retrieve()函数，过滤条件stBlh.sCompanyid字段必须设置值，否则无法检索成功
//          stBlh.sCompanyid影响与价格相关操作，若需要与价格类字段操作，必须设置正确的brokerId
//          若操作都与价格类字段无关，可以随便指定一个brokerId，建议最好设置正确的brokerId
//          由于Retrieve()函数没有做到接口隔离，导致stBlh所有参数设置必须正确，即使不关心的参数也要设置正确，否则会影响搜索正确性。
//          由于没有做到接口隔离导致大大增加了Retrieve()维护和使用成本，Retrieve()使用很广，维护时需谨慎。
//      5)、SetMap()函数，只有检索函数会自动调用SetMap()函数建立对应关系。
//          调用添加或者删除债券函数，最后要调用SetMap()函数建立对应关系，否则会影响查询等接口正确性。
//
//
//
//     常用用法说明：
//     方法一：只作为缓存债券简单容器，访问m_array_result数据，一般是从检索函数中得到内容。可以通过
//             AddBond()添加数据，Retrieve()检索数据，GetAt()和GetSize()遍历数据，
//
//
//     方法二：与borker相关债券容器，访问m_brokevec.m_vct数据。
//             可以通检索函数Retrieve()或者手动调用SetContent()得到m_brokevec.m_vct
//			   ss_sort()排序
//
//             检索函数Retrieve()或者SetContent()中参数bAll
//			   a)、bAll设置成false且过滤条件condStr.nHasFlg=0时（过滤条件成员nHasFlg默认为0）
//直接
//             m_array_result映射一份到m_brokevec.m_vct中，即m_array_result与m_brokevec.m_vct数据一样
//             注意过滤条件nHasFlg和sCompanyid参数设置，brokerkey.m_brokid =
//             condStr.sCompanyid。
//			   价格类操作需要通过brokerkey.m_brokid得到相关数据。
//             目前QB界面应用主要是采用此方法，而非方法一，排序方法主要针对m_brokevec.m_vct数据排序
//
//             b)、bAll设置成true时，会根据价格等因素，把满足条件的债券映射到m_brokevec.m_vct
//                 每个broker对应的数据，不一定m_array_result全部数据都满足条件。
//                 目前主要最优报价界面会设置成true，通常情况不要设置true。
//
//
//  -------------------------------------------------------------
//  author:	Tony
//    date: 2015-02-16
//   brief:
//    CSSVContainer债券缓存容器(虚拟容器)，负责缓存债券下标
//    目前CSSVContainer主要功能有：
//    1、缓存债券容器
//    2、缓存了broker及对应的债券下标容器
//	  3、检索功能
//    4、排序功能
//    5、调用AfxGetBondContainer()封装的一些辅助函数
//
//   SSVContainer修改记录：
//   1、删除了一些不再使用的成员函数和成员对象
//   2、增加一些易用性更好的接口
//   3、增加了注释代码
//  -------------------------------------------------------------
//  Copyright (C) 2015 - Sumscope All Rights Reserved
// ***************************************************************
//
// ***************************************************************

#ifdef CCORE_MAC
typedef std::function<int(const BrokerKey&, const BrokerKey&)> CSortFunction;
#else
typedef std::tr1::function<int(const BrokerKey&, const BrokerKey&)>
    CSortFunction;
#endif

typedef std::vector<CSortFunction> CSortFuncVector;

enum EM_CONTAINER_TYPE {
  CONTAINER_NULL = -1,
  BROKER_CONTAINER = 0,
  BANK_QUOTE_CONTAINER = 1,
  BANK_CLIENT_CONTAINER = 2,
  OVERSEA_CONTAINER = 3
};

typedef struct ContainerIndexType {
  int m_nVIndex;     // CSSVContainer,arrayResult下标
  int m_nBondIndex;  // bondcontainer索引
  int m_nPriority;
  ContainerIndexType() {
    m_nVIndex = -1;
    m_nBondIndex = -1;
    m_nPriority = -1;
  }
  void InitClear(void) {
    m_nVIndex = -1;
    m_nBondIndex = -1;
    m_nPriority = -1;
  }
} ContainerIndexData;

class CSSSortBondManager;
// 不要在这个类中随意添加函数！考虑重用现有函数or继承
class S_BONDLIB_EXPORT CSSVContainer {
 public:
  typedef std::vector<int> IntArray;
  typedef StringPtrMap BondKeyMap;

  CSSVContainer();
  CSSVContainer(const CSSVContainer& src);
  ~CSSVContainer();

  static CSSVContainer& availableBond();
  static CSSVContainer& availableAbsBond();
  static CSSVContainer& availableExBond();
  //-------------------------------------------------------------------------
  // Summary:
  // 		@add by Tony 2015.2.16 新增加易用性更好的常用操作接口函数
  //-------------------------------------------------------------------------
 public:
  CBondInfo* GetBond(
      const std::string& sBondKey,
      const std::string& sMarket);  // 根据Key查询债券，只在自己缓存容器中查询
  CBondInfo* GetBond(
      const std::string&
          sCombBondKey);  // 根据Key查询债券，只在自己缓存容器中查询

  CBondInfo* GetBond(int nBondIndex);      // 根据债券下标查询债券
  bool IsExistBond(int nBondIndex) const;  // true表示存在债券
  bool IsExistBond(const char* sBondKey,
                   const char* sListedMarket);  // true表示存在债券

  CBondInfo* GetBondByOwnIndex(int nOwnIndex);  // 根据自己容器下标查询债券对象
  int GetBondIndexByOwnIndex(int nOwnIndex);  // 根据自己容器下标查询债券下标

  //-------------------------------------------------------------------------
  // Summary:
  // 		向容器m_array_result中添加债券下标
  // Parameters:
  // 		nBondIndex - 债券下标
  // Returns:
  // 		若添加成功返回true,否则返回false
  //-------------------------------------------------------------------------
  bool AddBond(int nBondIndex);
  bool AddBond(const char* sBondKey, const char* sListedMarket);
  bool RemoveBond(const char* sBondKey, const char* sListedMarket);
  bool RemoveBondByOwnIndex(int nOwnIndex);

  //-------------------------------------------------------------------------
  // Summary:
  // 		建立m_array_result容器债券Key与债券下标的m_keymap关系
  //		注意：
  //           1、AddBond和RemoveBond接口，不会自动更新m_keymap，需要最后手动调用SetMap()
  //           2、检索债券函数会调用SetMap()
  // Parameters:
  // Returns:
  //
  //-------------------------------------------------------------------------
  bool SetMap();  // 建立债券Key与债券下标的关系
  void MarkMapDirty() { m_keymap_dirty = true; }
  bool SetMapImpl();
  void PrepareMap();

  //-------------------------------------------------------------------------
  // Summary:
  // 		根据m_array_result容器下标得到债券的下标
  // Parameters:
  // 		nOwnIndex - m_array_result自己的下标
  // Returns:
  // 		返回债券下标
  //-------------------------------------------------------------------------
  int GetAt(int nOwnIndex);
  int GetSize() const;  // 得到债券容器m_array_result大小
  bool Clear();         // 清除容器m_array_result和m_brokevec.m_vct数据
  const IntArray& GetData() const { return m_array_result; }
  void GetDataCopy(IntArray& data);
  void SetDataSafe(std::vector<int>&& data);

  // SSBrokerKeyVector m_brokevec对外接口
  // 排序等操作，针对是m_brokevec排序，估提供访问m_brokevec接口
 public:
  //-------------------------------------------------------------------------
  // Summary:
  // 		通过m_brokevec的下标，在m_brokevec中得到债券下标
  // Parameters:
  // 		nOwnIndex2 - m_brokevec的下标
  // Returns:
  // 		债券下标
  //-------------------------------------------------------------------------
  int GetBondIndex_Broker(int nOwnIndex2);
  int GetSize_Broker();                       // m_brokevec大小
  CBondInfo* GetBond_Broker(int nOwnIndex2);  // 债券指针
  const SSBrokerKeyVector& GetBrokerKeyVector() const { return m_brokevec; }
  BrokerKey GetBrokerKey(int nOwnIndex2) {
    if (nOwnIndex2 < 0 || nOwnIndex2 >= (int)m_brokevec.m_vct.size()) {
      return BrokerKey();
    }

    return m_brokevec.m_vct[nOwnIndex2];
  }

  void SetBrokerKey(int nOwnIndex2, const BrokerKey& obj) {
    if (nOwnIndex2 < 0 || nOwnIndex2 >= (int)m_brokevec.m_vct.size()) {
      return;
    }

    m_brokevec.m_vct[nOwnIndex2] = obj;
  }

  /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  // 以下是原来接口

  //-------------------------------------------------------------------------
  // Summary:
  // 		债券基本接口
  //-------------------------------------------------------------------------
 public:
  bool AddBondByID(int nBondIndex);  // 根据债券下标添加债券
  bool AddBondByKey(const char* sBondKey,
                    const char* sListedMarket);  // 根据债券Key添加债券
  bool RemoveBondByID(int nIndex);  // 根据债券下标删除债券
  bool RemoveBondByKey(const char* sBondKey,
                       const char* sListedMarket);  // 根据债券Key删除债

  //-------------------------------------------------------------------------
  // Summary:
  // 		建立Broker的Key与债券下标的关系
  // Parameters:
  // 		condStr - 过滤条件
  // 		bAll -
  // true表示全部Broker,false表示只建立condStr.sCompanyid与下标关系 Returns:
  // 		若更新成功返回true,否则返回false
  //-------------------------------------------------------------------------
  bool SetContent(BLHCONDITION& condStr, bool bAll = false);
  bool SetContent(const std::string& sCompanyId);

  //-------------------------------------------------------------------------
  // Summary:
  // 		检索函数
  //-------------------------------------------------------------------------
 public:
  //-------------------------------------------------------------------------
  // Summary:
  // 		根据过滤条件检索债券
  // Parameters:
  // 		condStr - 过滤条件
  // 		bAll -
  // RUE表示全部Broker,false表示只建立condStr.sCompanyid与下标关系 		pVC -
  // 指定债券容器，nullptr将在AfxGetBondContainer()中搜索 Returns:
  // 		若检索成功返回true,否则返回false
  //-------------------------------------------------------------------------
  bool Retrieve(BLHCONDITION& condStr, bool bAll = false,
                CSSVContainer* pVC = nullptr, bool bSecondaryMarket = true);

  //-------------------------------------------------------------------------
  // Summary:
  // 		根据类型和Key查询相应债券
  // Parameters:
  // 		nType - typeBondType等类型
  // 		szType - 关健字，拼音
  // 		pVC - 指定债券容器，nullptr将在AfxGetBondContainer()中搜索
  // Returns:
  // 		若成功返回true,否则返回false
  //-------------------------------------------------------------------------
  bool Retrieve(int nType, const char* szType, CSSVContainer* pVC = nullptr);

  //-------------------------------------------------------------------------
  // Summary:
  // 		根据类型和Key查询相应债券，更新放置到Broker债券容器中
  // Parameters:
  // 		nType - typeBondType等类型
  // 		szType - 关健字，拼音
  // 		m_brokls - 指定更新对应broker下的债券
  // 		pVC - 指定债券容器，nullptr将在AfxGetBondContainer()中搜索
  // Returns:
  // 		若成功返回true,否则返回false
  //-------------------------------------------------------------------------
  bool Retrieve(int nType, const char* szType, std::list<std::string>& m_brokls,
                CSSVContainer* pVC = nullptr);
  bool Retrieve(int nType, const char* szType, BLHCONDITION& condStr,
                CSSVContainer* pVC = nullptr);

  //-------------------------------------------------------------------------
  // Summary:
  //
  // Parameters:
  // 		nBondIndex - 债券下标
  // Returns:
  // 		债券仅对应该一个或者没有broker时，返回true
  //-------------------------------------------------------------------------
  bool IsNoBrokerBond(int nBondIndex);

  //-------------------------------------------------------------------------
  // Summary:
  // 		检索债券，从AfxGetBondContainer()中检索。这几个函数其实可以从上述Retrieve根据参数实现
  // Parameters:
  // 		condStr - 过滤条件
  // 		array_result - 满足条件的结果，传出参数
  // Returns:
  // 		若检索成功返回true,否则返回false
  //-------------------------------------------------------------------------
  bool Retrieve(BLHCONDITION& condStr, std::vector<int>& array_result,
                bool bSecondaryMarket = true);

  bool RetrieveFromStatic(BLHCONDITION& condStr, bool bAll = false);
  bool RetrieveFromStatic(int nType, const char* szType,
                          std::vector<int>& array_result);
  bool Retrieve(BLHCONDITION& condStr, char* FilterBondKey,
                std::vector<int>& array_result, bool bSecondaryMarket = true);

 public:
  /***************************************************************************************************
   *Para   :
   *retun  :
   *Remarks:
   *History:	2016/04/08 V1 devin.zhang
   ***************************************************************************************************/
  bool iRetrive(BLHCONDITION& condStr, bool bAll = false,
                CSSVContainer* pVC = nullptr, bool bSecondaryMarket = true,
                int nCallBackType = CBondInfo::FCT_NULL,
                _BONDFILTER BondFilter = nullptr);

  bool iRetrive(BLHCONDITION& condStr, std::vector<int>& array_result,
                bool bSecondaryMarket = true,
                int nCallBackType = CBondInfo::FCT_NULL,
                _BONDFILTER BondFilter = nullptr);

  bool iRetrive(BLHCONDITION& condStr, CBondInfo::MAP_BONDFILTER& mapBondFilter,
                bool bAll = false, CSSVContainer* pVC = nullptr,
                bool bSecondaryMarket = true);

  bool iRetrive(BLHCONDITION& condStr, CBondInfo::MAP_BONDFILTER& mapBondFilter,
                std::vector<int>& array_result, bool bSecondaryMarket = true);

  bool iRetrive(BLHCONDITION& condStr, bool bAll = false,
                int nCallBackType = CBondInfo::FCT_NULL,
                _BONDFILTER BondFilter = nullptr);

  //-------------------------------------------------------------------------
  // Summary:
  // 		得到报价函数，底层实际调用的是AfxGetBondContainer()的相应函数
  //-------------------------------------------------------------------------
 public:
  bool GetCompanyRepByKey(const char* szBondKey, const char* szKey,
                          REPORT& stRep);
  bool GetCompanyRepById(int nOwnIndex, const char* szKey,
                         REPORT& stRep);  // 根据自己容器下标查询报价
  bool GetCompanyRepByKey(const char* szBondKey, REPORT& stRep);
  bool GetCompanyRepById(int nOwnIndex,
                         REPORT& stRep);  // 根据自己容器下标查询报价
  int ElementAt(int nIndex);
  const CBondInfo& ElementAt2(
      int nOwnIndex) const;  // 虚拟容器中的index，不是全局的Index
  CBondCompanyRep* GetCompanyRep(const BrokerKey& szID);
  CBondCompanyRep* GetCompanyRep(
      int nOwnIndex);  // 虚拟容器中的index，不是全局的Index
  CBondBankRep* GetBankRep(int nOwnIndex);  // 虚拟容器中的index，不是全局的Index
  CBondBankRep* GetClntRep(int nOwnIndex);  // 虚拟容器中的index，不是全局的Index

  REPORT* GetCompanyInfoById(int nID);  // 虚拟容器中的index
  REPORT* GetCompanyInfoById(const std::string& szKey,
                             int nID);  // 虚拟容器中的index
  REPORT* GetCompanyInfoById(const std::string& szKey, const BrokerKey& szID);

  bool GetClentQuotByKey(const char* szBondKey, const char* szKey,
                         BKQUOTE& stQuot);

  static bool CheckBestPrice(const BLHCONDITION& Cond, const REPORT& report,
                             int nKey);
  static bool CheckBidPriceValid(const BLHCONDITION& Cond, const REPORT& report,
                                 int nKey);
  static bool CheckOfrPriceValid(const BLHCONDITION& Cond, const REPORT& report,
                                 int nKey);
  static bool CheckBidOfrPrice(const BLHCONDITION& Cond, const REPORT& report);
  static bool CheckBilateralBestPrice(const BLHCONDITION& Cond,
                                      const REPORT& report, int nKey);
  static bool CheckPriceValuate(const BLHCONDITION& Cond, const REPORT& report,
                                int nKey);
  static bool CheckBidCdcPriceValuate(const BLHCONDITION& Cond,
                                      const REPORT& report, int nKey,
                                      bool isMixedBP = false);
  static bool CheckCdcOfrPriceValuate(const BLHCONDITION& Cond,
                                      const REPORT& report, int nKey,
                                      bool isMixedBP = false);
  static bool CheckDiffPrice(
      const BLHCONDITION& Cond,
      const REPORT& report);  // 判断Diff >= (bid-ofr)*100
  static bool CheckBidVol(const BLHCONDITION& Cond, const REPORT& report);
  static bool CheckOfrVol(const BLHCONDITION& Cond, const REPORT& report);
  static bool CheckSettlementLite(const BLHCONDITION& Cond,
                                  const REPORT& report);
  static bool CheckQuotePriceTypeLite(
      const BLHCONDITION& Cond,
      const REPORT& report);  // 报价类型，实盘/可部分执行/意向
  static bool CheckSettlement(const BLHCONDITION& Cond, const REPORT& report);
  static bool IsPriceNeedShow(const BLHCONDITION& Cond, const REPORT& report,
                              int nKey, bool checkValidPrice = true);

  static bool CheckMixedBestPrice(const BLHCONDITION& Cond,
                                  const REPORT& report, int nKey);
  static bool CheckMixedBidPriceValid(const BLHCONDITION& Cond,
                                      const REPORT& report, int nKey);
  static bool CheckMixedOfrPriceValid(const BLHCONDITION& Cond,
                                      const REPORT& report, int nKey);
  static bool CheckMixedBilateralBestPrice(const BLHCONDITION& Cond,
                                           const REPORT& report, int nKey);
  static bool IsMixedBestPriceNeedShow(const BLHCONDITION& Cond,
                                       const REPORT& report, int nKey);

  static bool IsBondPassCondition(int nIndex, const BLHCONDITION& condStr,
                                  bool bSecondaryMarket,
                                  bool bAttention = false /*我的关注*/);
  static bool IsSSEFIBondPassCondition(int nIndex, const BLHCONDITION& condStr,
                                       bool bSecondaryMarket);
  static bool IsCFETSBondPassCondition(int nIndex, const BLHCONDITION& condStr,
                                       bool bSecondaryMarket);
  static bool IsCFETSDealPassCondition(int nIndex, const BLHCONDITION& condStr);
  static bool IsABSBondPassCondition(int nIndex, const BLHCONDITION& condStr,
                                     bool bSecondaryMarket);

  // 根据清盘速度重新组织REPORT
  static void RebuildReportBySettlement(const BLHCONDITION& Cond,
                                        const REPORT& rptSource,
                                        REPORT& rptDest, bool bForce = false);
  static bool RebuildQuoteVolumn(const BLHCONDITION& Cond,
                                 const PRICE_SETTLEMENT_LIST& lstPrice,
                                 PRICE& price);
  // 添加了删除Broker和债券下标数据
  void AddBrokerVector(const BrokerKey& brokerkey);
  bool DelBrokerVector(const BrokerKey& brokerkey);

  // 删除容器中的债券
  void DelBondVector(char* BondKey, BLHCONDITION& condStr, bool bAll = false);

  //-------------------------------------------------------------------------
  // Summary:
  // 		债券容器排序及相关函数
  //-------------------------------------------------------------------------
 public:
  //-------------------------------------------------------------------------
  // Summary:
  // 		Broker债券排序，不会改变自身容器m_array_result顺序，实际调用SortBrokerKey函数
  // Parameters:
  // 		vct_result - 传入和传出参数， 传出时为排序后的结果
  //				1)、vct_result.m_vct.size() ==
  //0时，会把m_brokevec.m_vct数据赋值给vct_result.m_vct，然后排序
  //              2)、vct_result.m_vct.size() != 0时,
  //              直接针对vct_result.m_vct排序
  // 		sort_key - 排序类型
  // 		szKey - brokerId，空值表示ALL Broker排序
  // 		bDesc - 排序方式
  // 		bSave -
  // true表示把排序后的结果保存到this，把vct_result赋值给m_brokevec.m_vct。否则不会修改m_brokevec.m_vct
  // Returns:
  // 		void
  //-------------------------------------------------------------------------
  void ss_sort(IN OUT SSBrokerKeyVector& vct_result, int sort_key,
               const std::string& szKey, bool bDesc = false, bool bSave = true);

  //-------------------------------------------------------------------------
  // Summary:
  // 		针对broker缓存容器排序，支持broker之间对同一债券的排序
  // Parameters:
  // 		array_result - broker缓存容器,是一个传出参数.、
  //                     1)、array_result.size() ==
  //                     0时，会把m_brokevec.m_vct数据赋值给array_result，然后排序
  //                     2)、array_result.size() != 0时,
  //                     直接针对array_result排序
  //                     3)、此函数不会修改m_brokevec.m_vct数据顺序
  // 		sort_key - 排序类型
  //      szKey    - brokerId，空值表示ALL Broker排序
  // 		bDesc - true表示降序，false表示升序
  // Returns:
  // 		void
  //-------------------------------------------------------------------------
  void SortBrokerKey(IN OUT std::vector<BrokerKey>& array_result, int sort_key,
                     const std::string& szKey, bool bDesc = false);

  // 排序辅助函数
  bool SetContainerType(int containerType);  // 设置债券容器
  bool SetLockTop(bool bLockTop = false);    // 设置置顶操作
  bool SetContent(const std::list<std::string>& m_brokls);
  void SetBondParam(int sort_key, const std::string& szKey,
                    bool bDesc);  // 设置排序项

  static inline bool GetTopCompare(const int& i, const int& j,
                                   const bool& bDesc = false,
                                   int sort_key = VMODIFY_TIME);
  static inline int GetTopCompareEx(const int& i, const int& j,
                                    const bool& bDesc = false,
                                    int sort_key = VMODIFY_TIME);
  static inline int CompareDouble(double dValue1, double dValue2);

  static inline double GetTakenPriceByKey(
      const char* pszKey, const char* pszMarket, void* pList,
      const std::string& brokerid);  // 获取当日成交价

  //-------------------------------------------------------------------------
  // Summary:
  // 		其它辅助函数
  //-------------------------------------------------------------------------
 public:
  // void	SetServerTime(time_t servertime);
  static time_t GetServerTime();
  int GetAllBondsSize();  // 得到所有债券数据容器大小
  // BLHCONDITION GetCondition(){return m_lcond;}	//得到过滤条件

  std::recursive_mutex& GetMutex() { return m_mutex; }

  // 重置基础数据
  void ResetArrayResult();

 public:
  static int CalMaturityTerm(const std::string& sPeriod);
  static int CalMaturityType(const std::string& sPeriod);
  static int GetRatingRank(const std::string& sRating);

  //////////////////////////////////////////////////////////////////////
  // 支持多层排序
 public:
  //-------------------------------------------------------------------------
  // Summary:
  // 		自己容器数据排序
  // Parameters:
  // 		vecSortInfo - 排序规则
  // Returns:
  // 		void
  //-------------------------------------------------------------------------
  void Sort(const CSortInfoManager& sortInfoMng,
            CSSSortBondManager* pSortBondMng = nullptr);

  //-------------------------------------------------------------------------
  // Summary:
  // 		对外接口,支持跨DLL操作,支持对外部数据排序
  // Parameters:
  // 		vecData -
  // 传入和传出参数，若vecData有值，则取vecData值排序，否则取容器本身数据进行排序
  // 		sortInfoMng - 排序规则
  // 		bUpdateContainer - TURE表示将排序结果更新本地容器
  // Returns:
  // 		void
  //-------------------------------------------------------------------------
  void Sort(IN OUT SSBrokerKeyVector& vecData,
            const CSortInfoManager& sortInfoMng, bool bUpdateContainer = true,
            CSSSortBondManager* pSortBondMng = nullptr);
  const CSortInfoManager& GetSortInfoMng() const { return m_sortInfoMng; }
  CSSSortBondManager* GetSortBondMng() { return m_pSortBondMng; }

  //-------------------------------------------------------------------------
  // Summary:
  // 		设置排序函数,支持外部传入比较函数
  // Parameters:
  // 		nSortKey - 排序类型 VSortKey
  // 		func - 比较函数
  // Returns:
  // 		void
  //-------------------------------------------------------------------------
  void SetSortFunction(int nSortKey, CSortFunction func);
  void ClearSortFunction() { m_mapSortFunc.clear(); }
  CSortFunction GetSortFunction(int nSortKey);

 private:
  void SortBrokerKey(IN OUT std::vector<BrokerKey>& array_result,
                     const CSortInfoManager& sortInfoMng);
  static void Extract(const std::vector<int>& source, std::vector<int>& dest,
                      const BLHCONDITION& condStr, bool bSecondaryMarket);

 public:
  static bool ExtractFrom(const std::vector<int>& source,
                          std::vector<int>& dest, const BLHCONDITION& condStr,
                          bool bSecondaryMarket);
  // 加搜索混合筛选 2022.6 add by lance
  // nType=0 BondCode/pinyin, nType=1 BondKey
  bool ExtractWithSearchString(std::vector<int>& dest, BLHCONDITION& condStr,
                               int nType, const char* sSearch,
                               bool bSecondaryMarket);

  void UpdateBestPricePush(BLHCONDITION& condStr, SSBrokerKeyVector& vct_result,
                           SSBrokerKeyVector& vct_resdel,
                           const std::list<xQBBestPriceUnit_c>& qblist,
                           bool bSecondaryMarket);
  void UpdateMixedBestPricePush(BLHCONDITION& condStr,
                                SSBrokerKeyVector& vct_result,
                                SSBrokerKeyVector& vct_resdel,
                                const QList<xQBMixedBestQuoteUnit_c>& qblist,
                                bool bSecondaryMarket);
  typedef std::map<int, CSortFunction> SortFuncMap;  // int:VSortKey
 public:                                             // broker缓存容器数据
  SSBrokerKeyVector m_brokevec;  // Broker与债券下标组合的vector数据
  bool
      m_bDataChanged;  // True表示m_brokevec数据有改变，变量服务于排序。只要m_brokevec数据发生变化了，需设置成true.否则为影响排序正确性
  int m_nNumTotalQuote;  // bank或者bankClient有效报价数量
  int m_nNumDiff2CDC;    // bank或者bankClient的EstPrc报价数量
 protected:
  // 多个市场流通的券只显示一个使用，记录优先显示key记录,在调用前先对每个key清一遍数据,
  std::map<std::string, ContainerIndexData> m_mapPerBondKey;

 protected:
  IntArray
      m_array_result;  // 债券下标容器,为了统一后续操作和更好扩展，该变量仅为过滤的过度数据变量，对外访问数据统一取m_brokevec数据
  bool m_keymap_dirty;
  BondKeyMap
      m_keymap;  // 债券Key与债券下标对应关系，目的是快速根据债券Key查询到债券
  std::recursive_mutex m_mutex;  // 互斥信号
 protected:                      // 检索
  BLHCONDITION m_lcond;          // 过滤条件
 protected:                      // 排序
  int m_ContainerType;           // 容器类型
  bool m_bLockTop;               // true表示置顶显示
  bool m_bDesc;                  // 排序 true表示降序
  int m_sort_key;                // 排序类型
  std::string m_szKey;           // 排序关健字，如公司名称

 private:
  CSortInfoManager m_sortInfoMng;      // 多重排序
  CSSSortBondManager* m_pSortBondMng;  // 排序加速类

  SortFuncMap m_mapSortFunc;  // 自定义排序函数map(VSortKey,CSortFunction)
};
